#pragma once
#include "World Definitions.h"

class Block
{
private:
	//all 4 bits are being used seperatley for different data
	// Buffer->0000-0000  Type->0000-0000  Trait->0000-0000  Trait Power->0000-0000
	// This gives each piece of data 256 options
	//  with the buffer just being extra space until its needed
	unsigned int BlockData;
public:
	Block():BlockData(0){}
	Block(unsigned int Data):BlockData(Data){}
	~Block(){BlockData=0;}

	//Basic operators
	// Checks to see if the blocks are exactly the same
	// TraitPow Trait Type AssetID
	bool operator ==(Block rhs) {
		if( BlockData == rhs.BlockData )
			return true;
		return false;
	}

	bool operator !=(Block rhs) {
		if( BlockData != rhs.BlockData )
			return true;
		return false;
	}

	void operator =(Block rhs) {
		BlockData = rhs.BlockData;
	}

	void operator =(unsigned int const & a_dat) {
		BlockData = a_dat;
	}

	bool operator <(unsigned int const & a_dat) {
		if( BlockData < a_dat ) return true;
		else return false;
	}

	bool operator >(unsigned int const & a_dat) {
		if( BlockData > a_dat ) return true;
		else return false;
	}

	//These should be used with care. {
		//These check to make sure the value is valid and then set it
		// for set type, it turns off all other bits that don't pertain to type
		inline void SetAssetID(unsigned int const & a_id) {BlockData |= (a_id & BLOCK_ASSET_ID_MASK);}
		inline void SetType(unsigned int const & a_type) {BlockData |= (a_type & BLOCK_TYPE_MASK);}
		inline void SetTrait(unsigned int const & a_trait) {BlockData |= (a_trait & BLOCK_TRAIT_MASK);}
		inline void SetTraitPow(unsigned int const & a_traitPow) {BlockData |= (a_traitPow & BLOCK_TRAIT_POW_MASK);}
		//Will set any value to the block that are not already on.
		inline void SetData(unsigned int const & a_data) {BlockData |= a_data;}
	//}

	//These are the safer versions of the above functions, and it
	// is recommended that you use these instead. {
		//Turns off all the bits for <insert> and the turns on all the new ones
		inline void SetAssetID_s(unsigned int const & a_id) {BlockData &= ~BLOCK_ASSET_ID_MASK;BlockData |= (a_id & BLOCK_ASSET_ID_MASK);}
		inline void SetType_s(unsigned int const & a_type) {BlockData &= ~BLOCK_TYPE_MASK;BlockData |= (a_type & BLOCK_TYPE_MASK);}
		inline void SetTrait_s(unsigned int const & a_trait) {BlockData &= ~BLOCK_TRAIT_MASK;BlockData |= (a_trait & BLOCK_TYPE_MASK);}
		inline void SetTraitPow_S(unsigned int const & a_traitPow) {BlockData &= ~BLOCK_TRAIT_POW_MASK;BlockData |= (a_traitPow & BLOCK_TYPE_MASK);}
		//Just switches out the data
		inline void SetData_s(unsigned int const & a_data) {BlockData = a_data;}
	//}

	//Clears out the <insert>
	inline void UnSetAssetID() {BlockData &= ~BLOCK_ASSET_ID_MASK;}
	inline void UnSetType() {BlockData &= ~BLOCK_TYPE_MASK;}
	inline void UnSetTrait() {BlockData &= ~BLOCK_TRAIT_MASK;}
	inline void UnSetTraitPow() {BlockData &= ~BLOCK_TRAIT_POW_MASK;}
	//Clears out any and all data
	inline void UnSetData() {BlockData = 0;}
	
	//Returns the <insert> of block only
	inline const unsigned int GetAssetID_s() const {return BlockData & BLOCK_ASSET_ID_MASK;}
	inline const unsigned int GetType_s() const {return BlockData & BLOCK_TYPE_MASK;}
	inline const unsigned int GetTrait_s() const {return BlockData & BLOCK_TRAIT_MASK;}
	inline const unsigned int GetTraitPow_s() const{return BlockData & BLOCK_TRAIT_POW_MASK;}
	//Returns the entire block data
	inline const unsigned int & GetData_s() const{return BlockData;}

	inline const unsigned int GetData_noAsset() const { return GetType_s() | GetTrait_s() | GetTraitPow_s(); }
};